<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SouleEngine文档</title>
    <style>
        :root {
            --bg-color: #0f0f17;
            --sidebar-bg: #1a1a2a;
            --text-color: #e0e0e0;
            --text-muted: #a0a0a0;
            --accent-color: #7a5af5;
            --code-bg: #1e1e2e;
            --border-color: #2a2a3a;
            --hover-bg: #2a2a3a;
        }
        
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
            background-color: var(--bg-color);
            color: var(--text-color);
            line-height: 1.6;
            display: flex;
            min-height: 100vh;
        }
        
        .sidebar {
            width: 280px;
            background-color: var(--sidebar-bg);
            height: 100vh;
            overflow-y: auto;
            position: sticky;
            top: 0;
            padding: 30px 0;
            border-right: 1px solid var(--border-color);
        }
        
        .sidebar-header {
            padding: 0 25px 20px;
            margin-bottom: 15px;
            border-bottom: 1px solid var(--border-color);
        }
        
        .sidebar-header h1 {
            font-size: 1.3rem;
            font-weight: 600;
            color: white;
            margin-bottom: 5px;
        }
        
        .sidebar-header p {
            font-size: 0.9rem;
            color: var(--text-muted);
        }
        
        .sidebar-nav {
            padding: 0 15px;
        }
        
        .sidebar-nav ul {
            list-style: none;
        }
        
        .sidebar-nav li {
            margin-bottom: 3px;
        }
        
        .sidebar-nav a {
            display: block;
            padding: 8px 12px;
            color: var(--text-color);
            text-decoration: none;
            border-radius: 6px;
            transition: all 0.2s ease;
            font-size: 0.95rem;
        }
        
        .sidebar-nav a:hover {
            background-color: var(--hover-bg);
            color: white;
        }
        
        .sidebar-nav a.active {
            background-color: var(--accent-color);
            color: white;
            font-weight: 500;
        }
        
        .sidebar-nav .section-title {
            color: var(--text-muted);
            font-size: 0.85rem;
            padding: 15px 12px 8px;
            margin-top: 10px;
            text-transform: uppercase;
            letter-spacing: 0.5px;
            font-weight: 600;
        }
        
        .main-content {
            flex: 1;
            padding: 40px 50px;
            max-width: 900px;
            margin: 0 auto;
        }
        
        h1, h2, h3, h4 {
            color: white;
            margin-bottom: 1.2rem;
            font-weight: 600;
        }
        
        h1 {
            font-size: 2.4rem;
            padding-bottom: 10px;
            border-bottom: 1px solid var(--border-color);
            margin-bottom: 2rem;
        }
        
        h2 {
            font-size: 1.8rem;
            margin-top: 3rem;
            padding-bottom: 0.5rem;
            border-bottom: 1px solid var(--border-color);
        }
        
        h3 {
            font-size: 1.4rem;
            margin-top: 2.5rem;
        }
        
        h4 {
            font-size: 1.1rem;
            margin-top: 2rem;
        }
        
        p {
            margin-bottom: 1.2rem;
            font-size: 1.05rem;
            line-height: 1.7;
        }
        
        a {
            color: var(--accent-color);
            text-decoration: none;
            font-weight: 500;
        }
        
        a:hover {
            text-decoration: underline;
        }
        
        pre {
            background-color: var(--code-bg);
            padding: 16px;
            border-radius: 8px;
            overflow-x: auto;
            margin: 1.5rem 0;
            border: 1px solid var(--border-color);
            font-size: 0.95rem;
            line-height: 1.5;
        }
        
        code {
            font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
            color: #e0e0e0;
        }
        
        p code, li code {
            background-color: var(--code-bg);
            padding: 0.2em 0.4em;
            border-radius: 4px;
            font-size: 0.9em;
            border: 1px solid var(--border-color);
        }
        
        ul, ol {
            margin-bottom: 1.5rem;
            padding-left: 1.8rem;
        }
        
        li {
            margin-bottom: 0.5rem;
            line-height: 1.6;
        }
        
        table {
            width: 100%;
            border-collapse: collapse;
            margin: 1.5rem 0;
            border: 1px solid var(--border-color);
            border-radius: 8px;
            overflow: hidden;
        }
        
        th, td {
            padding: 12px 16px;
            text-align: left;
            border-bottom: 1px solid var(--border-color);
        }
        
        th {
            background-color: var(--sidebar-bg);
            color: white;
            font-weight: 600;
        }
        
        tr:hover {
            background-color: var(--hover-bg);
        }

        .pop {
            color: #27ae60;
            font-weight: bold;
        }
        .oop {
            color: #e74c3c;
            font-weight: bold;
        }
        
        @media (max-width: 1024px) {
            .sidebar {
                width: 240px;
            }
            
            .main-content {
                padding: 30px;
            }
        }
        
        @media (max-width: 768px) {
            body {
                flex-direction: column;
            }
            
            .sidebar {
                width: 100%;
                height: auto;
                position: relative;
                border-right: none;
                border-bottom: 1px solid var(--border-color);
                padding: 20px 0;
            }
            
            .main-content {
                padding: 25px;
            }
        }
    </style>
  
    <link rel="stylesheet" href="../css/newpvsc.css" />
    <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
</head>
<body>
    <!-- 侧边栏导航 -->
    <div class="sidebar">
        <div class="sidebar-header">
            <h1>SoulEngine文档</h1>
            <p>FOR SoulEngine v2.3.4</p>
        </div>
        <nav class="sidebar-nav">
            <ul>
                <li class="section-title">入门指南</li>
                <li><a href="../index.html">注意事项</a></li>
                <li><a href="../pages/s1-download.html">下载与配置</a></li>
            </ul>
            <ul>
                <li class="section-title">基础开发</li>
                <li><a href="../pages/s2-basics.html">基础入门</a></li>
                <li><a href="../pages/s2-sprites.html">贴图与弹幕</a></li>
                <li><a href="../pages/s2-typer.html">文本与打字机</a></li>
                <li><a href="../pages/s2-collisions.html">碰撞</a></li>
                <li><a href="../pages/s2-player.html">玩家</a></li>
                <li><a href="../pages/s2-camera.html">摄像机</a></li>
                <li><a href="../pages/s2-easings.html">缓动</a></li>
                <li><a href="../pages/s2-shaders.html">着色器</a></li>
                <li><a href="../pages/s2-audio.html">音频</a></li>
                <li><a href="../pages/s2-globals.html">全局变量</a></li>
                <li><a href="../pages/s2-keyboard.html">按键检测</a></li>
                <li><a href="../pages/s2-window.html">游戏窗口</a></li>
            </ul>
            <ul>
                <li class="section-title">进阶开发</li>
                <li><a href="../pages/s3-gamejolt.html">Gamejolt API</a></li>
                <li><a href="../pages/s3-json.html">JSON</a></li>
            </ul>
            <ul>
                <li class="section-title">遭遇战斗</li>
                <li><a href="../pages/s4-scenes.html">场景介绍</a></li>
                <li><a href="../pages/s4-battle.html">战斗场景</a></li>
            </ul>
            <ul>
                <li class="section-title">其余页面</li>
                <li><a href="../pages/se-keyslist.html">键盘表</a></li>
                <li><a href="../pages/lua-tutorial.html">Lua教程</a></li>
            </ul>
        </nav>
    </div>
    
    <!-- 主内容区域 -->
    <div class="main-content">
        <h2>学习Lua</h2>
        <p>
            SoulEngine使用Lua作为脚本语言，因此需要学习Lua的基础知识。<br>
            学习Lua的最好的地方莫过于<a href="https://www.lua.org/manual/5.1/">Lua官方文档</a>。<br><br>

            不过如果你觉得从头系统的学习Lua还是<strong>太过于繁琐</strong>，更何况还有很多学到的东西是用不到制作游戏中的。<br>
            可以直接查看本文档附带的一份<a href="../pages/lua-tutorial.html">Lua教程</a>，里面包含了很多基础的、非常常用的内容。<br>
            <br>
            总而言之，<strong>在开始之前，学会Lua是十分重要的</strong>
        </p>
        <h2>面向过程与面向对象的编程</h2>
        <p>
            在SoulEngine中<br>
            <strong>UI</strong>主要使用面向过程的编程。<br>
            因为UI如何操作是一个非常简单而确定的逻辑，所以使用面向过程的编程。<br><br>

            <strong>玩家、GB、骨头等</strong>拥有面向对象的操作。<br>
            对于一个GB来说，GB拥有动画、开火逻辑等操作，每一部分都是独立的，因此使用面向对象的编程。<br><br>
            
            <strong>
                POP（面向过程）的优势：在简单、确定性问题中，“直给”的代码比“设计”的架构更有效。<br>
                OOP（面向对象）的优势：在不确定的问题之中，“用合理的架构减少繁琐的更改”。<br>
                你需要根据自己项目需求选择适合的编程方式。
            </strong>
        </p>
        <table>
            <thead>
                <tr>
                    <th>对比维度</th>
                    <th>面向过程 (POP)</th>
                    <th>面向对象 (OOP)</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td><strong>核心单元</strong></td>
                    <td class="pop">函数</td>
                    <td class="oop">类与对象</td>
                </tr>
                <tr>
                    <td><strong>代码组织</strong></td>
                    <td class="pop">按步骤分解</td>
                    <td class="oop">按实体和关系抽象</td>
                </tr>
                <tr>
                    <td><strong>复用性</strong></td>
                    <td class="pop">低（依赖函数库）</td>
                    <td class="oop">高（继承/组合）</td>
                </tr>
                <tr>
                    <td><strong>扩展性</strong></td>
                    <td class="pop">差（需修改流程）</td>
                    <td class="oop">好（通过多态/接口）</td>
                </tr>
                <tr>
                    <td><strong>性能</strong></td>
                    <td class="pop">更高（无抽象开销）</td>
                    <td class="oop">较低（对象管理开销）</td>
                </tr>
                <tr>
                    <td><strong>适合规模</strong></td>
                    <td class="pop">小型、线性问题</td>
                    <td class="oop">大型、复杂系统</td>
                </tr>
            </tbody>
        </table>

        <h3>面向对象的示例</h3>
        <pre>
            <code class="language-lua">
                -- 面向对象（OOP）的示例
                local Bone = {}
                Bone.__index = Bone

                function Bone:init()
                    self.color = {1, 0, 0}
                    self.length = 50
                    self.angle = 0

                    return self
                end

                function Bone:getLength()
                    return self.length
                end
            </code>
        </pre>
        在上述情况下，你创建的<strong>每一根</strong>骨头都会有上面所定义的init和getLength等方法。<br>
        如下，bone1和bone2都拥有<strong>自己的</strong>方法：
        <pre>
            <code class="language-lua">
                local bone = Bone:init()
                print(bone:getLength()) -- 输出：50

                local bone2 = Bone:init()
                print(bone2:getLength()) -- 输出：50
            </code>
        </pre>

        <h3>面向过程的示例</h3>
        <pre>
            <code class="language-lua">
                -- 面向过程（POP）的示例
                function initBone()
                    local bone = {}
                    bone.color = {1, 0, 0}
                    bone.length = 50
                    bone.angle = 0

                    return bone
                end

                function getBoneLength(bone)
                    return bone.length
                end
            </code>
        </pre>
        在上述情况下，你创建的<strong>每一根</strong>骨头都由你自己决定每一步的过程<br>
        如下，bone1和bone2都需要<strong>第三方</strong>方法来得到相同的结果：
        <pre>
            <code class="language-lua">
                local bone = initBone()
                print(getBoneLength(bone)) -- 输出：50

                local bone2 = initBone()
                print(getBoneLength(bone2)) -- 输出：50
            </code>
        </pre>
        <br>
        <strong>二者的明显区别在此暂时无法体现出来，只是能方便读者弄清使用方法。</strong><br><br>
        使用骨头的案例，就是为了说明，骨头们也可以拥有独自的长度、角度、以及颜色。<br>
        但是，所有的骨头，都有一个共同点，那就是它们都可以对玩家造成伤害、都拥有三个贴图进行首尾相连……<br>
        因此，面向对象在此处相当简单。每个骨头只需要执行各自<strong>早已写好</strong>的逻辑。
    </div>
</body>
</html>